package org.mnswf.desktopwidget.update {
	
	import flash.net.SharedObject;
	import flash.net.URLLoader;
	import flash.net.URLStream;
	import flash.net.URLRequest;
	import flash.filesystem.File;
	import flash.events.Event;
	import flash.system.Updater;
	import flash.filesystem.FileStream;
	import flash.filesystem.FileMode;
	import flash.utils.ByteArray;
	
	public class UpdateManager {
		
		private var preferences:SharedObject;
		private var appDescriptorLoader:URLLoader;
		private var releaseDefinitionLoader:URLLoader;
		private var installStream:URLStream;
		private var updateDialog:UpdateDialog;
		
		public function get isUpdatePending():Boolean {
			return preferences.data.pendingUpdate != null && preferences.data.pendingUpdate;
		}
		
		public function UpdateManager() {
			preferences = SharedObject.getLocal("UpdateManager");
			if(isUpdatePending) {
				updateDialog = UpdateDialog.show();
				updateDialog.addEventListener(UpdateDialog.START_INSTALL, onStartInstall, false, 0, true);
				updateDialog.currentState = "updateReady";
			}else {
				if(preferences.data.lastUpdateCheck != null) {
					var threeDays:Number = (((1000 * 60) * 60) * 24) * 3;
					var checkAgain:Date = new Date(preferences.data.lastUpdateCheck.valueOf() + threeDays)
					if(checkAgain < new Date()) {
						checkForUpdates();
					}
				}else {
					checkForUpdates();
				}
			}
		}
		
		private function checkForUpdates():void {
			var request:URLRequest = new URLRequest();
			var file:File = File.applicationResourceDirectory.resolve("META-INF/AIR/application.xml");
			if(file.exists) {
				request.url = file.url;
				appDescriptorLoader = new URLLoader();
				appDescriptorLoader.addEventListener(Event.COMPLETE, onDescriptorComplete, false, 0, true);
				appDescriptorLoader.load(request);
			}
		}
		
		private function onDescriptorComplete(event:Event):void {
			var request:URLRequest = new URLRequest();
			request.url = "http://www.mnswf.org/widget/release.xml";
			releaseDefinitionLoader = new URLLoader();
			releaseDefinitionLoader.addEventListener(Event.COMPLETE, onReleaseComplete, false, 0, true);
			releaseDefinitionLoader.load(request);
		}
		
		private function onReleaseComplete(event:Event):void {
			preferences.data.lastUpdateCheck = new Date();
			preferences.flush();
			if(XML(appDescriptorLoader.data).@version.toString() != XML(releaseDefinitionLoader.data).@version.toString()) {
				updateDialog = UpdateDialog.show();
				updateDialog.addEventListener(UpdateDialog.START_INSTALL, onStartInstall, false, 0, true);
				var request:URLRequest = new URLRequest();
				request.url = "http://www.mnswf.org/widget/" + XML(releaseDefinitionLoader.data).@file.toString();
				installStream = new URLStream();
				installStream.addEventListener(Event.COMPLETE, onInstallLoadComplete, false, 0, true);
				installStream.load(request);
			}
		}
		
		private function onInstallLoadComplete(event:Event):void {
			var fileData:ByteArray = new ByteArray();
			installStream.readBytes(fileData, 0, installStream.bytesAvailable);
			var file:File = File.applicationStorageDirectory.resolve("update.air");
		    var fileStream:FileStream = new FileStream();
		    fileStream.addEventListener(Event.CLOSE, onInstallFileClosed, false, 0, true);
		    fileStream.openAsync(file, FileMode.WRITE);
		    fileStream.writeBytes(fileData, 0, fileData.length);
		    fileStream.close();
		}
		
		private function onInstallFileClosed(event:Event):void {
		    preferences.data.pendingUpdate = true;
		    preferences.data.pendingUpdateVersion = XML(releaseDefinitionLoader.data).@version.toString();
		    preferences.flush();
			updateDialog.currentState = "updateReady";
		}
		
		private function onStartInstall(event:Event):void {
			updateDialog.close();
			update();
		}
		
		public function update():Boolean {
			if(isUpdatePending) {
				preferences.data.pendingUpdate = false;
				preferences.flush();
				var updater:Updater = new Updater();
				var file:File = File.applicationStorageDirectory.resolve("update.air");
				updater.update(file, preferences.data.pendingUpdateVersion);
				return true;
			}
			return false;
		}
		
	}
	
}